
#ifndef _IPC_THREAD_H_
#define _IPC_THREAD_H_

#if defined(WIN32) || defined(WIN64) || defined(WINCE) || defined(_MSC_VER)
/* ---------- Windows begin ---------- */

#include <windows.h>
#if !defined(WINCE)
#include <process.h>
#endif
#include <io.h>

/* 锁方法 */
#define ipcthread_mutex_t CRITICAL_SECTION
#define ipcthread_mutex_init(lpMutex, lpAttr) InitializeCriticalSection(lpMutex)
#define ipcthread_mutex_destroy(lpMutex) DeleteCriticalSection(lpMutex)
#define ipcthread_mutex_lock(lpMutex) EnterCriticalSection(lpMutex)
#define ipcthread_mutex_unlock(lpMutex) LeaveCriticalSection(lpMutex)

/* 线程创建 (自动释放无需join) */
#define ipcthread_create(lpPriv, lpCallback) _beginthread((void(*)(void*))lpCallback, 0, (void*)lpPriv)
/* 对于win版,上面 _beginthread 会返回handle可用于线程同步 */
#define ipcthread_join(handle) { WaitForSingleObject(handle, INFINITE); CloseHandle(handle); }

/* ---------- Windows end ---------- */
#else
/* ---------- Linux begin ---------- */
#include <pthread.h>

/* 锁方法 */
#define ipcthread_mutex_t pthread_mutex_t
#define ipcthread_mutex_init(lpMutex, lpAttr) pthread_mutex_init(lpMutex, lpAttr)
#define ipcthread_mutex_destroy(lpMutex) pthread_mutex_destroy(lpMutex)
#define ipcthread_mutex_lock(lpMutex) pthread_mutex_lock(lpMutex)
#define ipcthread_mutex_unlock(lpMutex) pthread_mutex_unlock(lpMutex)

/* 线程创建 (自动释放无需join) */
#if defined(APPLEOS) || defined(__cplusplus)
static void ipcthread_create(void *priv, void* (*callback)(void *)) /* c++的线程函数有返回值 */
#else
static void ipcthread_create(void *priv, void (*callback)(void *))
#endif
{
    pthread_t th;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    /* 禁用线程同步,线程运行结束后自动释放 */
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    pthread_create(&th, &attr, callback, priv);
    pthread_attr_destroy(&attr);
}

/* ---------- Linux end ---------- */
#endif

class CIpcAutoLock
{
public:
	explicit CIpcAutoLock(ipcthread_mutex_t& lock) : m_lock(lock) {
		ipcthread_mutex_lock(&m_lock);
	}
	~CIpcAutoLock() {
		ipcthread_mutex_unlock(&m_lock);
	}
private:
	ipcthread_mutex_t& m_lock;
};

#endif // _IPC_THREAD_H_
